<template>
  <el-dialog
    title="正则表达式测试"
    :visible.sync="dialogVisible"
    width="80%"
    :before-close="handleClose"
    @close="handleDialogClose"
  >
    <div class="regex-test-container">
      <!-- 模板信息显示 -->
      <el-card class="template-info" shadow="never">
        <div slot="header">
          <span>模板信息</span>
        </div>
        <el-descriptions :column="2" border>
          <el-descriptions-item label="模板名称">
            {{ templateName }}
          </el-descriptions-item>
          <el-descriptions-item label="描述">
            {{ templateDescription }}
          </el-descriptions-item>
        </el-descriptions>
      </el-card>

      <!-- 正则表达式测试区域 -->
      <el-card class="regex-test-area" shadow="never">
        <div slot="header">
          <span>正则表达式测试</span>
        </div>

        <div v-if="!isTemplateValid" class="no-template-tip">
          <el-alert
            title="未选择模板"
            description="请先选择一个有效的模板进行正则表达式测试"
            type="warning"
            :closable="false"
            show-icon
          />
        </div>

        <el-tabs v-else v-model="activeTab" type="card">
          <!-- Preparing正则测试 -->
          <el-tab-pane label="Preparing正则" name="preparing">
            <div class="regex-test-panel">
              <div class="regex-display">
                <h4>正则表达式:</h4>
                <el-input
                  :value="preparingRegex"
                  type="textarea"
                  :rows="3"
                  readonly
                  class="regex-input"
                />
              </div>
              <div class="test-input">
                <h4>测试日志:</h4>
                <el-input
                  v-model="preparingTestLog"
                  type="textarea"
                  :rows="5"
                  placeholder="请输入要测试的Preparing日志..."
                  @input="testPreparingRegex"
                />
              </div>
              <div class="test-result">
                <h4>测试结果:</h4>
                <div v-if="preparingResult" class="result-success">
                  <el-alert
                    title="匹配成功!"
                    type="success"
                    :closable="false"
                    show-icon
                  />
                  <div class="capture-groups">
                    <h5>捕获组:</h5>
                    <el-table :data="preparingCaptures" border size="small">
                      <el-table-column prop="name" label="组名" width="150" />
                      <el-table-column prop="value" label="值" />
                    </el-table>
                  </div>
                </div>
                <div v-else-if="preparingTestLog" class="result-error">
                  <el-alert
                    title="匹配失败"
                    type="error"
                    :closable="false"
                    show-icon
                  />
                </div>
                <div v-else class="result-empty">
                  <el-alert
                    title="请输入测试日志"
                    type="info"
                    :closable="false"
                    show-icon
                  />
                </div>
              </div>
            </div>
          </el-tab-pane>

          <!-- Parameters正则测试 -->
          <el-tab-pane label="Parameters正则" name="parameters">
            <div class="regex-test-panel">
              <div class="regex-display">
                <h4>正则表达式:</h4>
                <el-input
                  :value="parametersRegex"
                  type="textarea"
                  :rows="3"
                  readonly
                  class="regex-input"
                />
              </div>
              <div class="test-input">
                <h4>测试日志:</h4>
                <el-input
                  v-model="parametersTestLog"
                  type="textarea"
                  :rows="5"
                  placeholder="请输入要测试的Parameters日志..."
                  @input="testParametersRegex"
                />
              </div>
              <div class="test-result">
                <h4>测试结果:</h4>
                <div v-if="parametersResult" class="result-success">
                  <el-alert
                    title="匹配成功!"
                    type="success"
                    :closable="false"
                    show-icon
                  />
                  <div class="capture-groups">
                    <h5>捕获组:</h5>
                    <el-table :data="parametersCaptures" border size="small">
                      <el-table-column prop="name" label="组名" width="150" />
                      <el-table-column prop="value" label="值" />
                    </el-table>
                  </div>
                </div>
                <div v-else-if="parametersTestLog" class="result-error">
                  <el-alert
                    title="匹配失败"
                    type="error"
                    :closable="false"
                    show-icon
                  />
                </div>
                <div v-else class="result-empty">
                  <el-alert
                    title="请输入测试日志"
                    type="info"
                    :closable="false"
                    show-icon
                  />
                </div>
              </div>
            </div>
          </el-tab-pane>

          <!-- Total正则测试 -->
          <el-tab-pane label="Total正则" name="total">
            <div class="regex-test-panel">
              <div class="regex-display">
                <h4>正则表达式:</h4>
                <el-input
                  :value="totalRegex"
                  type="textarea"
                  :rows="3"
                  readonly
                  class="regex-input"
                />
              </div>
              <div class="test-input">
                <h4>测试日志:</h4>
                <el-input
                  v-model="totalTestLog"
                  type="textarea"
                  :rows="5"
                  placeholder="请输入要测试的Total日志..."
                  @input="testTotalRegex"
                />
              </div>
              <div class="test-result">
                <h4>测试结果:</h4>
                <div v-if="totalResult" class="result-success">
                  <el-alert
                    title="匹配成功!"
                    type="success"
                    :closable="false"
                    show-icon
                  />
                  <div class="capture-groups">
                    <h5>捕获组:</h5>
                    <el-table :data="totalCaptures" border size="small">
                      <el-table-column prop="name" label="组名" width="150" />
                      <el-table-column prop="value" label="值" />
                    </el-table>
                  </div>
                </div>
                <div v-else-if="totalTestLog" class="result-error">
                  <el-alert
                    title="匹配失败"
                    type="error"
                    :closable="false"
                    show-icon
                  />
                </div>
                <div v-else class="result-empty">
                  <el-alert
                    title="请输入测试日志"
                    type="info"
                    :closable="false"
                    show-icon
                  />
                </div>
              </div>
            </div>
          </el-tab-pane>
        </el-tabs>
      </el-card>

      <!-- 示例日志 -->
      <el-card class="sample-logs" shadow="never">
        <div slot="header">
          <span>示例日志</span>
        </div>
        <div v-if="!isTemplateValid" class="no-template-tip">
          <el-alert
            title="未选择模板"
            description="请先选择一个有效的模板查看示例日志"
            type="warning"
            :closable="false"
            show-icon
          />
        </div>
        <el-collapse v-else v-model="activeCollapse">
          <el-collapse-item title="MyBatis日志示例" name="mybatis">
            <div class="sample-log-item">
              <h5>Preparing日志:</h5>
              <el-input
                v-model="sampleLogs.preparing"
                type="textarea"
                :rows="2"
                readonly
                @click.native="copyToClipboard(sampleLogs.preparing)"
              />
            </div>
            <div class="sample-log-item">
              <h5>Parameters日志:</h5>
              <el-input
                v-model="sampleLogs.parameters"
                type="textarea"
                :rows="2"
                readonly
                @click.native="copyToClipboard(sampleLogs.parameters)"
              />
            </div>
            <div class="sample-log-item">
              <h5>Total日志:</h5>
              <el-input
                v-model="sampleLogs.total"
                type="textarea"
                :rows="2"
                readonly
                @click.native="copyToClipboard(sampleLogs.total)"
              />
            </div>
          </el-collapse-item>
        </el-collapse>
      </el-card>
    </div>

    <div slot="footer" class="dialog-footer">
      <el-button @click="handleClose">关闭</el-button>
      <el-button type="primary" @click="clearAllTests">清空测试</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { Vue } from 'vue';

export default {
  name: "RegexTestDialog",
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    template: {
      type: Object,
      default: () => ({}),
    },
  },
  data() {
    return {
      activeTab: "preparing",
      activeCollapse: ["mybatis"],
      preparingTestLog: "",
      parametersTestLog: "",
      totalTestLog: "",
      preparingResult: false,
      parametersResult: false,
      totalResult: false,
      preparingCaptures: [],
      parametersCaptures: [],
      totalCaptures: [],
      sampleLogs: {
        preparing:
          "2024-01-15 10:30:45.123 DEBUG [http-nio-8080-exec-1] com.example.mapper.UserMapper.selectUser - ==>  Preparing: SELECT * FROM users WHERE id = ?",
        parameters:
          "2024-01-15 10:30:45.124 DEBUG [http-nio-8080-exec-1] com.example.mapper.UserMapper.selectUser - ==> Parameters: 1(Integer)",
        total:
          "2024-01-15 10:30:45.125 DEBUG [http-nio-8080-exec-1] com.example.mapper.UserMapper.selectUser - <==      Total: 1",
      },
    };
  },
  computed: {
    dialogVisible: {
      get() {
        return this.visible;
      },
      set(val) {
        this.$emit("update:visible", val);
      },
    },
    isTemplateValid() {
      return this.template && Object.keys(this.template).length > 0;
    },
    templateName() {
      return (this.template && this.template.name) || '未选择模板';
    },
    templateDescription() {
      return (this.template && this.template.description) || '无描述';
    },
    preparingRegex() {
      return (this.template && this.template.preparingRegex) || '';
    },
    parametersRegex() {
      return (this.template && this.template.parametersRegex) || '';
    },
    totalRegex() {
      return (this.template && this.template.totalRegex) || '';
    },
  },
  watch: {
    visible(newVal) {
      if (newVal) {
        this.resetTestData();
      } else {
        this.resetTestData();
      }
    },
  },
  methods: {
    handleClose() {
      this.resetTestData();
      this.$emit("close");
      this.dialogVisible = false;
    },
    handleDialogClose() {
      this.resetTestData();
    },
    resetTestData() {
      this.preparingTestLog = "";
      this.parametersTestLog = "";
      this.totalTestLog = "";
      this.preparingResult = false;
      this.parametersResult = false;
      this.totalResult = false;
      this.preparingCaptures = [];
      this.parametersCaptures = [];
      this.totalCaptures = [];
    },
    testPreparingRegex() {
      if (!this.preparingTestLog || !this.template || !this.template.preparingRegex) {
        this.preparingResult = false;
        this.preparingCaptures = [];
        return;
      }
      this.testRegex(
        this.template.preparingRegex,
        this.preparingTestLog,
        "preparing"
      );
    },
    testParametersRegex() {
      if (!this.parametersTestLog || !this.template || !this.template.parametersRegex) {
        this.parametersResult = false;
        this.parametersCaptures = [];
        return;
      }
      this.testRegex(
        this.template.parametersRegex,
        this.parametersTestLog,
        "parameters"
      );
    },
    testTotalRegex() {
      if (!this.totalTestLog || !this.template || !this.template.totalRegex) {
        this.totalResult = false;
        this.totalCaptures = [];
        return;
      }
      this.testRegex(this.template.totalRegex, this.totalTestLog, "total");
    },
    testRegex(regexStr, testText, type) {
      if (!regexStr || !testText) {
        this[`${type}Result`] = false;
        this[`${type}Captures`] = [];
        return;
      }
      try {
        const regex = new RegExp(regexStr);
        const match = testText.match(regex);

        if (match) {
          this[`${type}Result`] = true;
          this[`${type}Captures`] = this.extractNamedGroups(regex, match);
        } else {
          this[`${type}Result`] = false;
          this[`${type}Captures`] = [];
        }
      } catch (error) {
        this[`${type}Result`] = false;
        this[`${type}Captures`] = [];
        this.$message.error(`正则表达式错误: ${error.message}`);
      }
    },
    extractNamedGroups(regex, match) {
      const captures = [];
      if (!Array.isArray(match)) return captures;
      const groupNames = this.getNamedGroups(regex);

      groupNames.forEach((name, index) => {
        if (match[index + 1] !== undefined) {
          captures.push({
            name: name,
            value: match[index + 1],
          });
        }
      });

      return captures;
    },
    getNamedGroups(regex) {
      const groupNames = [];
      const regexStr = regex.source;
      const namedGroupRegex = /\(\?<([^>]+)>/g;
      let match;

      while ((match = namedGroupRegex.exec(regexStr)) !== null) {
        groupNames.push(match[1]);
      }

      return groupNames;
    },
    copyToClipboard(text) {
      navigator.clipboard
        .writeText(text)
        .then(() => {
          this.$message.success("已复制到剪贴板");
        })
        .catch(() => {
          this.$message.error("复制失败");
        });
    },
    clearAllTests() {
      this.resetTestData();
      this.$message.success("已清空所有测试数据");
    },
  },
};
</script>

<style scoped>
.regex-test-container {
  max-height: 70vh;
  overflow-y: auto;
}

.template-info {
  margin-bottom: 20px;
}

.regex-test-area {
  margin-bottom: 20px;
}

.sample-logs {
  margin-bottom: 20px;
}

.regex-test-panel {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.regex-display h4,
.test-input h4,
.test-result h4 {
  margin: 0 0 10px 0;
  color: #303133;
  font-weight: 500;
}

.regex-input {
  font-family: "Courier New", monospace;
  font-size: 12px;
}

.capture-groups {
  margin-top: 15px;
}

.capture-groups h5 {
  margin: 0 0 10px 0;
  color: #606266;
}

.result-success,
.result-error,
.result-empty {
  margin-top: 10px;
}

.sample-log-item {
  margin-bottom: 15px;
}

.sample-log-item h5 {
  margin: 0 0 8px 0;
  color: #606266;
  font-size: 14px;
}

.sample-log-item .el-input {
  cursor: pointer;
}

.sample-log-item .el-input:hover {
  border-color: #409eff;
}

.dialog-footer {
  text-align: right;
}

.no-template-tip {
  margin: 20px 0;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .regex-test-panel {
    gap: 15px;
  }

  .el-descriptions {
    font-size: 12px;
  }
}
</style> 